package com.boot.dog.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.boot.dog.common.auth.DogUser;
import com.boot.dog.common.util.ApiResult;
import com.boot.dog.common.util.Result;
import com.boot.dog.common.util.SecurityUtil;
import com.boot.dog.entities.ao.RoleAo;
import com.boot.dog.entities.dto.RolePermissionDto;
import com.boot.dog.entities.pojo.Role;
import com.boot.dog.entities.pojo.RolePermission;
import com.boot.dog.entities.pojo.UserRole;
import com.boot.dog.entities.vo.RoleVo;
import com.boot.dog.mapper.RoleMapper;
import com.boot.dog.mapper.RolePermissionMapper;
import com.boot.dog.mapper.UserRoleMapper;
import com.boot.dog.service.RoleService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: MaxLv
 * @Date: 2020/1/13
 */
@Service
@AllArgsConstructor
public class RoleServiceImpl implements RoleService {

    private final RoleMapper roleMapper;

    private final RolePermissionMapper rolePermissionMapper;

    private final UserRoleMapper userRoleMapper;

    @Override
    public ApiResult<IPage<RoleVo>> getRoles(Page page, RoleAo ao) {
        DogUser authUser = SecurityUtil.getUser();
        ao.setCurrentUser(authUser.getUsername());
        IPage<RoleVo> vos = roleMapper.selectByPage(page, ao);
        if (vos.getTotal() > 0) {
            vos.getRecords().forEach(vo -> {
                List<RolePermission> rolePermissions = roleMapper.selectPermissionIdsByRoleId(vo.getId());
                vo.setRolePermission(rolePermissions);
            });
        }
        return Result.of(vos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResult<Void> saveRole(Role role) {
        Integer count = roleMapper.selectCount(Wrappers.<Role>query().lambda().eq(Role::getName, role.getName()));
        if (count > 0) {
            return Result.warn("角色名称已存在");
        }
        roleMapper.insert(role);
        return Result.ok("新增角色成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResult<Void> editRole(Role role) {
        Integer count = roleMapper.selectCount(Wrappers.<Role>query().lambda().eq(Role::getName, role.getName()).ne(Role::getId, role.getId()));
        if (count > 0) {
            return Result.warn("角色名称已存在");
        }
        roleMapper.updateById(role);
        return Result.ok("编辑角色成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResult<Void> delById(Integer id) {
        Integer userCount = userRoleMapper.selectCount(Wrappers.<UserRole>query().lambda().eq(UserRole::getRoleId, id));
        if (userCount > 0) {
            return Result.warn("角色已分配给用户,无法删除");
        }
        rolePermissionMapper.delete(Wrappers.<RolePermission>query().lambda().eq(RolePermission::getRoleId, id));
        roleMapper.deleteById(id);
        return Result.ok("删除角色成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResult<Void> editRolePerm(RolePermissionDto dto) {
        rolePermissionMapper.delete(Wrappers.<RolePermission>query().lambda().eq(RolePermission::getRoleId, dto.getRoleId()));
        if (CollUtil.isNotEmpty(dto.getPermIds())) {
            List<RolePermission> rolePermissions = dto.getPermIds().stream().map(permId -> {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setPermissionId(permId);
                rolePermission.setRoleId(dto.getRoleId());
                return rolePermission;
            }).collect(Collectors.toList());
            rolePermissionMapper.insertBatch(rolePermissions);
        }
        return Result.ok("分配权限成功");
    }

    @Override
    public ApiResult<List<Role>> getAllRole() {
        String currentUser = SecurityUtil.getUser().getUsername();
        List<Role> roles = roleMapper.selectAllRole(currentUser);
        return Result.of(roles);
    }


}
